/*
 * BZip2.java
 *
 * Created on 13 January 2007, 15:15
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package libjdc.util;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.tools.bzip2.CBZip2InputStream;
import org.apache.tools.bzip2.CBZip2OutputStream;

/**
 *
 * @author root
 */
public class BZip2 {
    
    private static boolean readFileHeader(InputStream bis) throws IOException {
        if ((bis.read() != 'B') || (bis.read() != 'Z')) {
            return false;
        }
        return true;
    }
    
    public static boolean isBZ2(String fileName){
        return fileName.endsWith("bz2");
    }
    
    public static void unpack(File src) throws IOException {
        InputStream uin = new FileInputStream(  src );
        readFileHeader(uin);
        File dst = new File(src.getParent()+File.separator+src.getName().substring(0,src.getName().indexOf(".bz2"))); 
        InputStream in = new CBZip2InputStream( uin );
        OutputStream out = new FileOutputStream(dst);
    
        // Transfer bytes from in to out
        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
        }
        in.close();
        out.close();
        System.out.println(dst.toString());
    }
    
    public static InputStream getInputStream(String fileName,File current) throws FileNotFoundException, IOException, UnkownFormatException{
        InputStream input;
        if(BZip2.isBZ2(fileName)){
            InputStream uin = new FileInputStream(  current );
            
            if (!BZip2.readFileHeader(uin)) {
                throw new UnkownFormatException("Formato incorreto");
            }
            return new CBZip2InputStream( uin );
        }else
            throw new UnkownFormatException("Formato incorreto");
        
    }
    
    /**
     * Compacta o ficheiro source para BZ2 e coloca-o na mma direcoria
     * @param source 
     * @author dbotelho
     */
    public static void pack(File source) {
        pack(source,new File(source.getAbsolutePath()+".bz2"));
    }
    
    public static void pack(File source,File zipFile) {
        CBZip2OutputStream zOut = null;
        try {
            BufferedOutputStream bos =
                    new BufferedOutputStream(new FileOutputStream(zipFile));
            bos.write('B');
            bos.write('Z');
            zOut = new CBZip2OutputStream(bos);
            zipFile(source, zOut);
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } finally {
            if (zOut != null) {
                try {
                    // close up
                    zOut.close();
                } catch (IOException e) {
                    //ignore
                }
            }
        }
    }
    
    /**
     * zip a file to an output stream
     * @param file the file to zip
     * @param zOut the output stream
     * @throws IOException on error
     */
    public static void zipFile(File file, OutputStream zOut)
            throws IOException {
        FileInputStream fIn = new FileInputStream(file);
        try {
            zipFile(fIn, zOut);
        } finally {
            fIn.close();
        }
    }
    
    /**
     * zip a stream to an output stream
     * @param in   the stream to zip
     * @param zOut the output stream
     * @throws IOException
     */
    private static void zipFile(InputStream in, OutputStream zOut)
            throws IOException {
        byte[] buffer = new byte[8 * 1024];
        int count = 0;
        do {
            zOut.write(buffer, 0, count);
            count = in.read(buffer, 0, buffer.length);
        } while (count != -1);
    }
    
}
